package com.sec.etech.common.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sec.etech.common.constant.DBConstant;
import com.sec.etech.org.service.EtechUserUtil;
import com.sec.etech.sys.util.ContextUtil;
import org.openbpm.bpm.core.mapper.BpmTaskOpinionExtMapper;
import org.openbpm.bpm.core.model.BpmTaskOpinion;
import org.openbpm.bpm.core.model.BpmTaskOpinionExt;
import org.openbpm.org.core.manager.RoleManager;
import org.openbpm.sys.api.service.ISysDataSourceService;
import org.openbpm.sys.api.service.SerialNoService;
import org.openbpm.sys.core.manager.SerialNoManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class CommonService {
    @Resource
    SerialNoManager serialNoManager;
    @Resource
    SerialNoService serialNoService;

    @Resource
    BpmTaskOpinionExtMapper taskOpinionExtMapper;

    @Autowired
    RoleManager roleManager;
    @Autowired
    private ISysDataSourceService sysDataSourceService;

    @Autowired
    EtechFlowCheckHelper etechFlowCheckHelper;

    @Resource
    JdbcTemplate jdbcTemplate;

    // 检查当前用户是否管理员
    public boolean isAdmin() {
        // etech 固定配置
        return ContextUtil.currentUserIsAdmin() || "9".equals(ContextUtil.getCurrentUserId()) || "417137619324108800".equals(ContextUtil.getCurrentUserId());
    }

    //检查当前是否管理员
    public boolean isAdmin(String uid) {
        return "9".equals(uid) || "417137619324108800".equals(uid) || EtechUserUtil.getUserAdmin().getUserId().equals(uid);
    }

    /// <summary>当前用户是否某设计科室的计划班组长：批量或单独设定设计校对、计划任务列入
    /// </summary>
    /// <returns></returns>
    public boolean isManager() {
        Long uid = Long.parseLong(ContextUtil.getCurrentUserId());
        String str = "SELECT first a.managersid ";
        str += "FROM proj_plantask_z_designdprt_managers AS a,proj_plantask_z_designdprt AS b ";
        str += "WHERE a.designdprtid=b.designdprtid AND a.active=1 AND b.active=1 AND a.uid=" + uid;
        JdbcTemplate jdbcTemplate = sysDataSourceService.getJdbcTemplateByKey(DBConstant.PLAN_DB);
        Long managersId = null;
        try {
            managersId = jdbcTemplate.queryForObject(str, Long.class);
        } catch (Exception e) {
        }
        return managersId != null && managersId > 0 && managersId.longValue() == uid.longValue();
    }

    /// <summary>当前用户是否特定设计科室的计划班组长，或者平台管理员：批量或单独设定设计校对、计划任务列入
    /// </summary>
    /// <returns></returns>
    public boolean isManager(String designdprtid) {
        Long uid = Long.parseLong(ContextUtil.getCurrentUserId());
        String str = "SELECT a.uid ";
        str += "FROM proj_plantask_z_designdprt_managers AS a,proj_plantask_z_designdprt AS b ";
        str += "WHERE a.designdprtid=b.designdprtid AND a.active=1 AND b.active=1 ";
        str += "AND b.designdprtid=" + designdprtid + " AND a.uid=" + uid + " limit 1";
        JdbcTemplate jdbcTemplate = sysDataSourceService.getJdbcTemplateByKey(DBConstant.PLAN_DB);
        Long managersId = null;
        try {
            managersId = jdbcTemplate.queryForObject(str, Long.class);
        } catch (Exception e) {
        }
        if (managersId == null || managersId == 0 || managersId == -1) {//PLAN平台的管理员拥有一切权限
            return isAdmin();
        } else return managersId != null;
    }

    // 检查当前用户是否具有某角色
    public boolean hasRole(String role) {
        /*if (role == null) return false;
        // 管理员特权
        if (isAdmin()) return true;
        List<Role> roles = roleManager.getByUserId(ContextUtil.getCurrentUserId());
        for (Role role1 : roles) {
            if (role.equalsIgnoreCase(role1.getAlias())) {
                return true;
            }
        }
        return false;*/
        return this.hasRole(role, ContextUtil.getCurrentUserId());
    }

    // 检查指定用户是否具有某角色
    public boolean hasRole(String role, String uid) {
        if(role == null) {return false;}
        // 管理员特权
        if (isAdmin(uid)) {return true;}

        return EtechUserUtil.checkUserHasRole(role);

//        List<Role> roles = roleManager.getByUserId(uid);
//        for (Role role1 : roles) {
//            if (role.equalsIgnoreCase(role1.getAlias())) {
//                return true;
//            }
//        }
//        return false;
    }

    /**
     * 检查当前流程是否处于指定节点
     *
     * @param instId
     * @param bizId
     * @param nodeKeys
     * @return
     */
    public boolean isInCurrentNodes(String instId, String bizId, String[] nodeKeys) {
        //
        return etechFlowCheckHelper.isInCurrentNodes(instId, bizId, nodeKeys);
    }

    /**
     * 检查当前流程是否已全部通过指定节点
     *
     * @param instId
     * @param bizId
     * @param nodeKeys
     * @return
     */
    public boolean havePassedNodes(String instId, String bizId, String[] nodeKeys) {
        //
        return etechFlowCheckHelper.havePassedNodes(instId, bizId, nodeKeys);
    }

    // 获取指定流程的当前节点
    public String[] getNodesInFlow(String instId, String bizId) {
        // TODO 先查instId 后查bizId
        List<String> nodeList = new ArrayList<>();
        List<BpmTaskOpinionExt> taskList = taskOpinionExtMapper.selectList(new QueryWrapper<BpmTaskOpinionExt>()
                .lambda().eq(BpmTaskOpinion::getInstId, instId).eq(BpmTaskOpinionExt::getStatus, "awaiting_check"));
        for (BpmTaskOpinionExt taskOpinionExt : taskList) {
            nodeList.add(taskOpinionExt.getTaskKey());
        }
        return nodeList.toArray(new String[nodeList.size()]);
    }

    // 获取指定流程的当前节点
    public Map<String, String> getNodesMapInFlow(String instId, String bizId) {
        // TODO 先查instId 后查bizId
        List<String> nodeList = new ArrayList<>();
        List<BpmTaskOpinionExt> taskList = taskOpinionExtMapper.selectList(new QueryWrapper<BpmTaskOpinionExt>()
                .lambda().eq(BpmTaskOpinion::getInstId, instId).eq(BpmTaskOpinionExt::getStatus, "awaiting_check"));
        Map<String, String> map = new HashMap<>();
        for (BpmTaskOpinionExt taskOpinionExt : taskList) {
            map.put(taskOpinionExt.getTaskKey(), taskOpinionExt.getTaskId());
        }
        return map;
    }

    /**
     * 检查当前流程是否已经结束
     *
     * @param instanceId
     * @return
     */
    public boolean isInstanceEnd(String instanceId) {
        return etechFlowCheckHelper.isInstanceEnd(instanceId);
    }

    /**
     * 获取指定流水号下一个值
     *
     * @param alias
     * @return
     * @throws Exception
     */
    public String getNextIdByAlias(String alias) {
        if (this.serialNoManager.isAliasExisted(null, alias)) {
            String nextId = this.serialNoService.genNextNo(alias);
            return nextId;
        }
        return null;
    }

    /**
     * 获取指定流水号当前的值
     *
     * @param alias
     * @return
     */
    public String getPreviewNoByAlias(String alias) {
        if (this.serialNoManager.isAliasExisted(null, alias)) {
            return this.serialNoService.getPreviewNo(alias);
        }
        return null;
    }

    /// <summary>根据需求科室ID获取对应班组长ID
    /// </summary>
    public List<Long> getManagers(Long designdprtid) {
        String sql = "SELECT uid FROM proj_plantask_z_designdprt_managers WHERE active=1 AND designdprtid=" + designdprtid.longValue();
        JdbcTemplate jdbcTemplate = sysDataSourceService.getJdbcTemplateByKey(DBConstant.PLAN_DB);
        return jdbcTemplate.queryForList(sql, Long.TYPE);
    }

    //直接根据用户id获取科室班组长id列表，用于发邮件
    public List<String> getManagersByUserid(Long userId) {
        String sql = "SELECT b.uid  FROM `proj_plantask_z_designdprt` a " +
                "LEFT JOIN proj_plantask_z_designdprt_managers b ON a.designdprtid = b.designdprtid AND b.active = 1 " +
                "LEFT JOIN org_user_group_view c ON c.group_id_=a.dprtid " +
                "WHERE c.id_=" + userId;
        JdbcTemplate jdbcTemplate = sysDataSourceService.getJdbcTemplateByKey(DBConstant.PLAN_DB);
        return jdbcTemplate.queryForList(sql, String.class);
    }

    /**
     * jdbcTemplate.queryForMap 查不到或者查询多个会报错
     *
     * @param sql
     * @return
     */
    public Map<String, Object> queryForMap(String sql) {
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        if (CollUtil.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    /**
     * jdbcTemplate.queryForMap 查不到或者查询多个会报错
     *
     * @param sql
     * @param args
     * @return
     */
    public Map<String, Object> queryForMap(String sql, @Nullable Object... args) {
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, args);
        if (CollUtil.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    public <T> T queryForObject(String sql, Class<T> t) {
        Map<String, Object> map = queryForMap(sql);
        if (CollUtil.isNotEmpty(map)) {
            //如果是基本类型 或者基本类型的封装类 取map第一个key值
            if (t.isPrimitive()
                    || t.isAssignableFrom(String.class)
                    || t.isAssignableFrom(Integer.class)
                    || t.isAssignableFrom(Long.class)
                    || t.isAssignableFrom(Double.class)
                    || t.isAssignableFrom(Float.class)
                    || t.isAssignableFrom(Date.class)
                    || t.isAssignableFrom(LocalDateTime.class)
                    || t.isAssignableFrom(LocalDate.class)
                    || t.isAssignableFrom(Boolean.class)) {
                for (String key : map.keySet()) { //取第一个
                    return map.get(key) == null ? null : Convert.convert(t, map.get(key));
                }
            }
            return JSONUtil.toBean(JSONUtil.parseObj(map), t);
        }
        return null;
    }

    public <T> List<T> queryForListObject(String sql, Class<T> t) {
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        if (CollUtil.isNotEmpty(list)) {
            //如果是基本类型 或者基本类型的封装类 取map第一个key值
            List<T> newList = new ArrayList<>();
            boolean flag = false;
            if (t.isPrimitive()
                    || t.isAssignableFrom(String.class)
                    || t.isAssignableFrom(Integer.class)
                    || t.isAssignableFrom(Long.class)
                    || t.isAssignableFrom(Double.class)
                    || t.isAssignableFrom(Float.class)
                    || t.isAssignableFrom(Date.class)
                    || t.isAssignableFrom(LocalDateTime.class)
                    || t.isAssignableFrom(LocalDate.class)
                    || t.isAssignableFrom(Boolean.class)) {
                flag = true;
            }
            for (Map<String, Object> map : list) {
                if (flag) {
                    for (String key : map.keySet()) { //取第一个
                        newList.add(map.get(key) == null ? null : (T) map.get(key));
                        break;
                    }
                } else {
                    newList.add(JSONUtil.toBean(JSONUtil.parseObj(map), t));
                }
            }
            return newList;
        }
        return new ArrayList<T>();
    }

    /**
     * 判断流程中是否存在指定节点
     * @param instId
     * @param nodeKey
     * @return
     */
    public boolean hasNodeCode(String instId, String nodeKey){
        return etechFlowCheckHelper.hasNodeCode(instId, nodeKey);
    }

    public Long getLongValue(Long value) {
        return value == null ? 0L : value;
    }

    public Integer getIntegerValue(Integer value) {
        return value == null ? 0 : value;
    }

    public boolean getBooleanValue(Boolean value) {
        return value == null ? false : value;
    }

    public String getStrValue(Object value) {
        return value == null ? "" : String.valueOf(value);
    }

    public boolean comparedValue(Object value1, Object value2) {
        return getStrValue(value1).equals(getStrValue(value2));
    }
}
